home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_108 / bash-108.zoo / src / execute_cmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-12  |  66.8 KB  |  2,529 lines

  1. /* execute_command.c -- Execute a COMMAND structure. */
  2.  
  3. /* Copyright (C) 1987,1991 Free Software Foundation, Inc.
  4.  
  5.    This file is part of GNU Bash, the Bourne Again SHell.
  6.  
  7.    Bash is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 1, or (at your option)
  10.    any later version.
  11.  
  12.    Bash is distributed in the hope that it will be useful, but WITHOUT
  13.    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14.    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  15.    License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with Bash; see the file COPYING.  If not, write to the Free
  19.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. /**
  22.  ** (sjk)++ Needed for the new implimentation of do_piping()
  23.  **
  24.  **/
  25. #if defined(atarist)
  26. #include <osbind.h>
  27. #endif
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <sys/types.h>
  32. #ifndef SONY
  33. #include <fcntl.h>
  34. #endif
  35. #include <sys/file.h>
  36. #include "posixstat.h"
  37. #include <signal.h>
  38.  
  39. #ifndef SIGABRT
  40. #define SIGABRT SIGIOT
  41. #endif
  42.  
  43. #include <sys/param.h>
  44. #include <errno.h>
  45.  
  46. #include "shell.h"
  47. #include "y.tab.h"
  48. #include "builtins.h"
  49. #include "flags.h"
  50. #include "hash.h"
  51. #include "jobs.h"
  52.  
  53. #ifdef ALIAS
  54. #include "alias.h"
  55. #endif
  56.  
  57. #include "sysdefs.h"
  58.  
  59. int builtin_pipe_in = NO_PIPE;
  60. int builtin_pipe_out = NO_PIPE;
  61.  
  62. extern int breaking, continuing, loop_level;
  63. extern int errno;
  64. extern int interactive;
  65.  
  66. extern int getdtablesize ();
  67. extern char *strerror ();
  68.  
  69. #if defined (USG)
  70. extern int last_made_pid;
  71. #endif
  72.  
  73. extern WORD_LIST *expand_words (), *expand_word ();
  74. extern char *make_command_string ();
  75.  
  76. /* The value returned by the last synchronous command. */
  77. int last_command_exit_value = 0;
  78.  
  79. /* The list of redirections to preform which will undo the redirections
  80.    that I made in the shell. */
  81. REDIRECT *redirection_undo_list = (REDIRECT *)NULL;
  82.  
  83. #define FD_BITMAP_DEFAULT_SIZE 32
  84. /* Functions to allocate and deallocate the structures used to pass
  85.    information from the shell to its children about file descriptors
  86.    to close. */
  87. struct fd_bitmap *
  88. new_fd_bitmap (size)
  89.      long size;
  90. {
  91.   struct fd_bitmap *ret;
  92.  
  93.   ret = (struct fd_bitmap *)xmalloc (sizeof (struct fd_bitmap));
  94.  
  95.   ret->size = size;
  96.  
  97.   if (size)
  98.     {
  99.       ret->bitmap = (char *)xmalloc (size);
  100.       bzero (ret->bitmap, size);
  101.     }
  102.   else
  103.     ret->bitmap = (char *)NULL;
  104.   return (ret);
  105. }
  106.  
  107. void
  108. dispose_fd_bitmap (fdbp)
  109.      struct fd_bitmap *fdbp;
  110. {
  111.   if (fdbp->bitmap)
  112.     free (fdbp->bitmap);
  113.  
  114.   free (fdbp);
  115. }
  116.  
  117. void
  118. close_fd_bitmap (fdbp)
  119.      struct fd_bitmap *fdbp;
  120. {
  121.   register int i;
  122.  
  123.   if (fdbp)
  124.     {
  125.       for (i = 0; i < fdbp->size; i++)
  126.     if (fdbp->bitmap[i])
  127.       {
  128.         close (i);
  129.         fdbp->bitmap[i] = 0;
  130.       }
  131.     }
  132. }
  133.  
  134. /* Execute the command passed in COMMAND.  COMMAND is exactly what
  135.    read_command () places into GLOBAL_COMMAND.  See "shell.h" for the
  136.    details of the command structure.
  137.  
  138.    EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
  139.    return values.  Executing a command with nothing in it returns
  140.    success. */
  141. execute_command (command)
  142.      COMMAND *command;
  143. {
  144.   struct fd_bitmap *fd_close_bmap;
  145.   int r;
  146.  
  147.   fd_close_bmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
  148.  
  149.   /* Just do the command, but not asynchronously. */
  150.   r = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, fd_close_bmap);
  151.   dispose_fd_bitmap (fd_close_bmap);
  152.   return r;
  153. }
  154.  
  155. /* Returns 1 if TYPE is a shell control structure type. */
  156. int
  157. shell_control_structure (type)
  158.      enum command_type type;
  159. {
  160.   switch (type)
  161.     {
  162.     case cm_for:
  163.     case cm_case:
  164.     case cm_while:
  165.     case cm_until:
  166.     case cm_if:
  167.     case cm_group:
  168.       return (1);
  169.  
  170.     default:
  171.       return (0);
  172.     }
  173. }
  174.  
  175. /* A function to use to unwind_protect the redirection undo list
  176.    for loops. */
  177. cleanup_redirects (list)
  178.      REDIRECT *list;
  179. {
  180.   do_redirections (list, 1, 0, 0);
  181.   dispose_redirects (list);
  182. }
  183.  
  184. /* Function to unwind_protect the redirections for functions and builtins. */
  185. cleanup_func_redirects (list)
  186.      REDIRECT *list;
  187. {
  188.   do_redirections (list, 1, 0, 0);
  189. }
  190.  
  191. restore_e_flag (value)
  192.      int value;
  193. {
  194.   exit_immediately_on_error = value;
  195. }
  196.  
  197. open_files ()
  198. {
  199.   register int i;
  200.   int f, fd_table_size;
  201.  
  202.   fd_table_size = getdtablesize ();
  203.  
  204.   fprintf (stderr, "pid %d open files:", getpid ());
  205.   for (i = 3; i < fd_table_size; i++)
  206.     {
  207.       if ((f = fcntl (i, F_GETFD, 0)) != -1)
  208.     fprintf (stderr, " %d (%s)", i, f ? "close" : "open");
  209.     }
  210.   fprintf (stderr, "\n");
  211. }
  212.  
  213. execute_command_internal (command,
  214.               asynchronous,
  215.               pipe_in, pipe_out,
  216.               fds_to_close)
  217.      COMMAND *command;
  218.      int asynchronous;
  219.      int pipe_in, pipe_out;
  220.      struct fd_bitmap *fds_to_close;
  221. {
  222.   int exec_result = EXECUTION_SUCCESS;
  223.   REDIRECT *my_undo_list = (REDIRECT *)NULL;
  224.   int invert, old_error_exit;
  225.  
  226.   if (!command || breaking || continuing)
  227.     return (EXECUTION_SUCCESS);
  228.  
  229.   run_pending_traps ();        /* XXX */
  230.  
  231.   invert = command->invert_pipeline;
  232.  
  233.   /* If a command was being explicitly run in a subshell, or if it is
  234.      a shell control-structure, and it has a pipe, then we do the command
  235.      in a subshell. */
  236.  
  237.   if (command->subshell ||
  238.       (shell_control_structure (command->type) &&
  239.        (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous)))
  240.     {
  241.       int paren_pid;
  242.  
  243.       /* Fork a subshell, turn off the subshell bit, turn off job
  244.      control and call execute_command () on the command again. */
  245.       paren_pid = make_child (savestring (make_command_string (command)),
  246.                   asynchronous);
  247.       if (paren_pid == 0)
  248.     {
  249.       extern int interactive, login_shell;
  250.       int user_subshell, return_code;
  251.  
  252.       user_subshell = (command->subshell == WANT_SUBSHELL);
  253.       command->subshell = 0;
  254.  
  255.       /* If a command is asynchronous in a subshell (like ( foo ) & or
  256.          the special case of an asynchronous GROUP command where the
  257.          the subshell bit is turned on down in case cm_group: below), 
  258.          turn off `asynchronous', so that two subshells aren't spawned.
  259.  
  260.          This seems semantically correct to me.  For example, 
  261.          ( foo ) & seems to say ``do the command `foo' in a subshell
  262.          environment, but don't wait for that subshell to finish'',
  263.          and "{ foo ; bar } &" seems to me to be like functions or
  264.          builtins in the background, which executed in a subshell
  265.          environment.  I just don't see the need to fork two subshells. */
  266.  
  267.       /* Don't fork again, we are already in a subshell. */
  268.       asynchronous = 0;
  269.  
  270.       /* Subshells are neither login nor interactive. */
  271.       login_shell = interactive = 0;
  272.  
  273. #if defined (JOB_CONTROL)
  274.       /* Delete all traces that there were any jobs running.  This is
  275.          only for subshells. */
  276.       without_job_control ();
  277. #endif /* JOB_CONTROL */
  278.       do_piping (pipe_in, pipe_out);
  279.  
  280.       if (fds_to_close)
  281.         close_fd_bitmap (fds_to_close);
  282.  
  283.       if (command->redirects)
  284.         if (!(do_redirections (command->redirects, 1, 0, 0) == 0))
  285.           exit (EXECUTION_FAILURE);
  286.  
  287.       return_code =
  288.         execute_command_internal
  289.           (command, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
  290.  
  291.       /* If we were explicitly placed in a subshell with (), we need
  292.          to do the `shell cleanup' things, such as running traps[0]. */
  293.       if (user_subshell)
  294.         run_exit_trap ();
  295.  
  296.       exit (return_code);
  297.     }
  298.       else
  299.     {
  300.       close_pipes (pipe_in, pipe_out);
  301.  
  302.       /* If we are part of a pipeline, and not the end of the pipeline,
  303.          then we should simply return and let the last command in the
  304.          pipe be waited for.  If we are not in a pipeline, or are the
  305.          last command in the pipeline, then we wait for the subshell 
  306.          and return its exit status as usual. */
  307.       if (pipe_out != NO_PIPE)
  308.         return (EXECUTION_SUCCESS);
  309.  
  310.       stop_pipeline (asynchronous, (COMMAND *)NULL);
  311.  
  312.       if (!asynchronous)
  313.         {
  314.           last_command_exit_value = wait_for (paren_pid);
  315.  
  316.           /* If we have to, invert the return value. */
  317.           if (invert)
  318.         {
  319.           if (last_command_exit_value == EXECUTION_SUCCESS)
  320.             return (EXECUTION_FAILURE);
  321.           else
  322.             return (EXECUTION_SUCCESS);
  323.         }
  324.           else
  325.         return (last_command_exit_value);
  326.         }
  327.       else
  328.         {
  329.           extern int interactive;
  330.           if (interactive)
  331.         describe_pid (paren_pid);
  332.  
  333.           run_pending_traps ();        /* XXX */
  334.  
  335.           return (EXECUTION_SUCCESS);
  336.         }
  337.     }
  338.     }
  339.  
  340.   /* Handle WHILE FOR CASE etc. with redirections.  (Also '&' input
  341.      redirection.)  */
  342.   do_redirections (command->redirects, 1, 1, 0);
  343.   my_undo_list = (REDIRECT *)copy_redirects (redirection_undo_list);
  344.  
  345.   begin_unwind_frame ("loop_redirections");
  346.  
  347.   if (my_undo_list)
  348.     add_unwind_protect (cleanup_redirects, my_undo_list);
  349.  
  350.   old_error_exit = exit_immediately_on_error;
  351.   add_unwind_protect (restore_e_flag, old_error_exit);
  352.  
  353.   switch (command->type)
  354.     {
  355.     case cm_for:
  356.       exec_result = execute_for_command (command->value.For);
  357.       break;
  358.  
  359.     case cm_case:
  360.       exec_result = execute_case_command (command->value.Case);
  361.       break;
  362.  
  363.     case cm_while:
  364.       exec_result = execute_while_command (command->value.While);
  365.       break;
  366.  
  367.     case cm_until:
  368.       exec_result = execute_until_command (command->value.While);
  369.       break;
  370.  
  371.     case cm_if:
  372.       exec_result = execute_if_command (command->value.If);
  373.       break;
  374.  
  375.     case cm_group:
  376.  
  377.       /* This code can be executed from either of two paths: an explicit
  378.      '{}' command, or via a function call.  If we are executed via a
  379.      function call, we have already taken care of the function being
  380.      executed in the background (down there in execute_simple_command ()),
  381.      and this command should *not* be marked as asynchronous.  If we
  382.      are executing a regular '{}' group command, and asynchronous == 1,
  383.      we must want to execute the whole command in the background, so we
  384.      need a subshell, and we want the stuff executed in that subshell
  385.      (this group command) to be executed in the foreground of that
  386.      subshell (i.e. there will not be *another* subshell forked).
  387.  
  388.      What we do is to force a subshell if asynchronous, and then call
  389.      execute_command_internal again with asynchronous still set to 1,
  390.      but with the original group command, so the printed command will
  391.      look right.
  392.  
  393.      The code above that handles forking off subshells will note that
  394.      both subshell and async are on, and turn off async in the child
  395.      after forking the subshell (but leave async set in the parent, so
  396.      the normal call to describe_pid is made).  This turning off
  397.      async is *crucial*; if it is not done, this will fall into an
  398.      infinite loop of executions through this spot in subshell after
  399.      subshell until the process limit is exhausted. */
  400.  
  401.       if (asynchronous)
  402.     {
  403.       command->subshell = FORCE_SUBSHELL;
  404.       exec_result =
  405.         execute_command_internal (command, 1, pipe_in, pipe_out,
  406.                       fds_to_close);
  407.     }
  408.       else
  409.     {
  410.       exec_result =
  411.         execute_command_internal (command->value.Group->command,
  412.                       asynchronous, pipe_in, pipe_out,
  413.                       fds_to_close);
  414.     }
  415.       break;
  416.  
  417.     case cm_simple:
  418.       {
  419.     pid_t last_pid = last_made_pid;
  420.     
  421. #if defined (JOB_CONTROL)
  422.     extern int already_making_children;
  423. #endif /* JOB_CONTROL */
  424.     exec_result =
  425.       execute_simple_command (command->value.Simple, pipe_in, pipe_out,
  426.                   asynchronous, fds_to_close);
  427.  
  428.     /* The temporary environment should be used for only the simple
  429.        command immediately following its definition. */
  430.     dispose_used_env_vars ();
  431.  
  432.     /* If we forked to do the command, then we must
  433.        wait_for() the child. */
  434. #if defined (JOB_CONTROL)
  435.     if (already_making_children && pipe_out == NO_PIPE)
  436. #else
  437.       if (pipe_out == NO_PIPE)
  438. #endif /* JOB_CONTROL */
  439.         {
  440.           if (last_pid != last_made_pid)
  441.         {
  442.           stop_pipeline (asynchronous, (COMMAND *)NULL);
  443.  
  444.           if (asynchronous)
  445.             {
  446.               extern int interactive;
  447.  
  448.               if (interactive)
  449.             describe_pid (last_made_pid);
  450.             }
  451.           else
  452. #if !defined (JOB_CONTROL)
  453.             /* Do not wait for asyncronous processes started from
  454.                startup files. */
  455.             if (last_made_pid != last_asynchronous_pid)
  456. #endif
  457.               /* When executing a shell function that executes other
  458.              commands, this causes the last simple command in
  459.              the function to waited for twice. */
  460.               exec_result = wait_for (last_made_pid);
  461.         }
  462.         }
  463.       }
  464.       if (exit_immediately_on_error && !invert &&
  465.       (exec_result != EXECUTION_SUCCESS))
  466.     {
  467.       last_command_exit_value = exec_result;
  468.       longjmp (top_level, EXITPROG);
  469.     }
  470.  
  471.       break;
  472.  
  473.     case cm_connection:
  474.       switch (command->value.Connection->connector)
  475.     {
  476.       /* Do the first command asynchronously. */
  477.     case '&':
  478.       {
  479.         COMMAND *tc = command->value.Connection->first;
  480. #ifndef JOB_CONTROL
  481.         {
  482.           REDIRECT *tr = 
  483.         make_redirection (0, r_inputa_direction,
  484.                   make_word ("/dev/null"));
  485.           tr->next = tc->redirects;
  486.           tc->redirects = tr;
  487.         }
  488. #endif                /* !JOB_CONTROL */
  489.         exec_result = execute_command_internal (tc, 1, pipe_in, pipe_out,
  490.                             fds_to_close);
  491.         if (command->value.Connection->second)
  492.           exec_result =
  493.         execute_command_internal (command->value.Connection->second,
  494.                       asynchronous, pipe_in, pipe_out,
  495.                       fds_to_close);
  496.       }
  497.       break;
  498.  
  499.     case ';':
  500.       /* Just call execute command on both of them. */
  501.       execute_command (command->value.Connection->first); /* XXX might need fd to close here... */
  502.       exec_result =
  503.         execute_command_internal (command->value.Connection->second,
  504.                       asynchronous, pipe_in, pipe_out,
  505.                       fds_to_close);
  506.       break;
  507.  
  508.     case '|':
  509.       {
  510.         /* Make a pipeline between the two commands. */
  511.         int fildes[2];
  512.         if (pipe (fildes) < 0)
  513.           {
  514.         report_error ("pipe error: %s", strerror (errno));
  515. #if defined (JOB_CONTROL)
  516.         /* Because of the way Bash does pipes -- creating all pipe
  517.            file descriptors before starting any of the processes
  518.            involved -- this will generally find no processes to kill,
  519.            and no pipeline to dispose of.  If the Bash pipe execution
  520.            method is changed in the future, something like this will
  521.            be needed, so it stays. */
  522.         terminate_current_pipeline ();
  523.         kill_current_pipeline ();
  524. #endif
  525.         last_command_exit_value = EXECUTION_FAILURE;
  526.         /* The unwind-protects installed below will take care
  527.            of closing all of the open file descriptors. */
  528.         throw_to_top_level ();
  529.           }
  530.         else
  531.           {
  532.         /* Here is a problem: with the new file close-on-exec
  533.            code, the read end of the pipe (fildes[0]) stays open in
  534.            the first process, so that process will never get a
  535.            SIGPIPE.  There is no way to signal the first process that
  536.            it should close fildes[0] after forking, so it remains
  537.            open.  No SIGPIPE is ever sent because there is still a
  538.            file descriptor open for reading connected to the pipe.
  539.            We take care of that here.  This passes around a bitmap
  540.            of file descriptors that must be closed after making a
  541.            child process in execute_simple_command. */
  542. /** 
  543.  ** (sjk)++ This above described problem does not exists on the 
  544.  **         atari ST because of my brain dead pipe implementation.
  545.  **/
  546. #if !defined(atarist)
  547.         struct fd_bitmap *fd_bitmap1, *fd_bitmap2;
  548.         int newsize;
  549.  
  550.         /* We need fd_bitmap1 and fd_bitmap2 to be at least as big
  551.            as fildes[0] and fildes[1], respectively.  If fildes[0]
  552.            and fildes[1] are both less than fds_to_close->size, then
  553.            use fds_to_close->size. */
  554.  
  555.         if (fildes[0] < fds_to_close->size)
  556.           newsize = fds_to_close->size;
  557.         else
  558.           newsize = fildes[0] + 8;    /* XXX pick a number... */
  559.  
  560.         fd_bitmap1 = new_fd_bitmap (newsize);
  561.  
  562.         if (fildes[1] < fds_to_close->size)
  563.           newsize = fds_to_close->size;
  564.         else
  565.           newsize = fildes[1] + 8;    /* XXX any number... */
  566.  
  567.         fd_bitmap2 = new_fd_bitmap (newsize);
  568.  
  569.         /* Now copy the old information into the new bitmaps. */
  570.         bcopy (fds_to_close->bitmap, fd_bitmap1->bitmap,
  571.                fds_to_close->size);
  572.  
  573.         bcopy (fds_to_close->bitmap, fd_bitmap2->bitmap,
  574.                fds_to_close->size);
  575.         /* And mark the pipe file descriptors to be closed. */
  576.         fd_bitmap1->bitmap[fildes[0]] = 1;
  577.         fd_bitmap2->bitmap[fildes[1]] = 1; 
  578.  
  579.         /* In case there are pipe or out-of-processes errors, we
  580.            want all these file descriptors to be closed when
  581.            unwind-protects are run, and the storage used for the
  582.            bitmaps freed up. */
  583.         begin_unwind_frame ("pipe-file-descriptors");
  584.         add_unwind_protect (close_fd_bitmap, fd_bitmap1);
  585.         add_unwind_protect (close_fd_bitmap, fd_bitmap2);
  586.         add_unwind_protect (dispose_fd_bitmap, fd_bitmap1);
  587.         add_unwind_protect (dispose_fd_bitmap, fd_bitmap2);
  588.  
  589.         execute_command_internal (command->value.Connection->first,
  590.                       asynchronous, pipe_in, fildes[1],
  591.                       fd_bitmap1);
  592.  
  593.         exec_result =
  594.           execute_command_internal (command->value.Connection->second,
  595.                         asynchronous, fildes[0], pipe_out,
  596.                         fd_bitmap2);
  597. #else 
  598.         execute_command_internal (command->value.Connection->first,
  599.                       asynchronous, pipe_in, fildes[1],
  600.                       fds_to_close);
  601.  
  602.         exec_result =
  603.           execute_command_internal (command->value.Connection->second,
  604.                         asynchronous, fildes[0], pipe_out,
  605.                         fds_to_close);
  606. #endif
  607.  
  608. #if !defined(atarist)
  609.         /* We cannot call close_fd_bitmap () here.  Doing so will
  610.            cause pipelines with > 2 processes to hang. */
  611.         dispose_fd_bitmap (fd_bitmap1);
  612.         dispose_fd_bitmap (fd_bitmap2);
  613.         discard_unwind_frame ("pipe-file-descriptors");
  614. #endif
  615.           }
  616.       }
  617.       break;
  618.  
  619.     case AND_AND:
  620.       if (asynchronous)
  621.         {
  622.           /* If we have something like a && b &, run the && stuff in a
  623.          subshell.  Force a subshell and just call
  624.          execute_command_internal again.  Leave asynchronous on
  625.          so that we get a report from the parent shell about the
  626.          background job. */
  627.           command->subshell = FORCE_SUBSHELL;
  628.           exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
  629.           break;
  630.         }
  631.  
  632.       /* Execute the first command.  If the result of that is successful,
  633.          then execute the second command, otherwise return. */
  634.       exit_immediately_on_error = 0;
  635.       if ((exec_result = execute_command (command->value.Connection->first))
  636.           == EXECUTION_SUCCESS)
  637.         {
  638.           exit_immediately_on_error += old_error_exit;
  639.           exec_result = execute_command (command->value.Connection->second);
  640.         }
  641.       else
  642.         exit_immediately_on_error += old_error_exit;
  643.  
  644.       break;
  645.  
  646.     case OR_OR:
  647.       if (asynchronous)
  648.         {
  649.           /* If we have something like a || b &, run the || stuff in a
  650.          subshell.  Force a subshell and just call
  651.          execute_command_internal again.  Leave asynchronous on
  652.          so that we get a report from the parent shell about the
  653.          background job. */
  654.           command->subshell = FORCE_SUBSHELL;
  655.           exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
  656.           break;
  657.         }
  658.  
  659.       /* Execute the first command.  If the result of that is successful,
  660.          then return, otherwise execute the second command. */
  661.       exit_immediately_on_error = 0;
  662.       if ((exec_result = execute_command (command->value.Connection->first))
  663.           != EXECUTION_SUCCESS)
  664.         {
  665.           exit_immediately_on_error += old_error_exit;
  666.           exec_result =  execute_command (command->value.Connection->second);
  667.         }
  668.       else
  669.         exit_immediately_on_error += old_error_exit;
  670.       break;
  671.     
  672.     default:
  673.       programming_error ("Bad connector `%d'!",
  674.                  command->value.Connection->connector);
  675.       longjmp (top_level, DISCARD);
  676.       break;
  677.     }
  678.       break;
  679.       
  680.     case cm_function_def:
  681.       exec_result = intern_function (command->value.Function_def->name,
  682.                      command->value.Function_def->command);
  683.       break;
  684.  
  685.     default:
  686.       programming_error ("execute_command: Bad command type `%d'!",
  687.              command->type);
  688.     }
  689.  
  690.   if (my_undo_list)
  691.     {
  692.       do_redirections (my_undo_list, 1, 0, 0);
  693.       dispose_redirects (my_undo_list);
  694.     }
  695.  
  696.   discard_unwind_frame ("loop_redirections");
  697.  
  698.   /* Invert the return value if we have to */
  699.   if (invert)
  700.     {
  701.       if (exec_result == EXECUTION_SUCCESS)
  702.     exec_result = EXECUTION_FAILURE;
  703.       else
  704.     exec_result = EXECUTION_SUCCESS;
  705.     }
  706.  
  707.   last_command_exit_value = exec_result;
  708.   run_pending_traps ();            /* XXX */
  709.   return (last_command_exit_value);
  710. }
  711.  
  712. /* Execute a FOR command.  The syntax is: FOR word_desc IN word_list;
  713.    DO command; DONE */
  714. execute_for_command (for_command)
  715.      FOR_COM *for_command;
  716. {
  717.   /* I just noticed that the Bourne shell leaves word_desc bound to the
  718.      last name in word_list after the FOR statement is done.  This seems
  719.      wrong to me; I thought that the variable binding should be lexically
  720.      scoped, i.e. only would last the duration of the FOR command.  This
  721.      behaviour can be gotten by turning on the lexical_scoping switch. */
  722.  
  723.   extern int breaking, continuing;
  724.   register WORD_LIST *releaser, *list;
  725.   WORD_DESC *temp = for_command->name;
  726.   char *identifier;
  727.   SHELL_VAR *old_value;        /* Remember the old value of x. */
  728.   int retval = EXECUTION_SUCCESS;
  729.  
  730.   if (!check_identifier (temp))
  731.     return (EXECUTION_FAILURE);
  732.  
  733.   loop_level++;
  734.   identifier = temp->word;
  735.  
  736.   list = releaser = expand_words (for_command->map_list, 0);
  737.  
  738.   if (lexical_scoping)
  739.     old_value = copy_variable (find_variable (identifier));
  740.  
  741.   while (list)
  742.     {
  743.       QUIT;
  744.       bind_variable (identifier, list->word->word);
  745.       execute_command (for_command->action);
  746.       retval = last_command_exit_value;
  747.       QUIT;
  748.  
  749.       if (breaking)
  750.     {
  751.       breaking--; 
  752.       break;
  753.     }
  754.  
  755.       if (continuing)
  756.     {
  757.       continuing--;
  758.       if (continuing)
  759.         break;
  760.     }
  761.  
  762.       list = list->next;
  763.     }
  764.   dispose_words (releaser);
  765.  
  766.   loop_level--;
  767.   
  768.   if (lexical_scoping)
  769.     {
  770.       if (!old_value)
  771.     {
  772.       makunbound (identifier, shell_variables);
  773.     }
  774.       else
  775.     {
  776.       SHELL_VAR *new_value;
  777.  
  778.       new_value = bind_variable (identifier, value_cell(old_value));
  779.       new_value->attributes = old_value->attributes;
  780.     }
  781.       dispose_variable (old_value);
  782.     }
  783.   return (retval);
  784. }
  785.  
  786. /* Execute a CASE command.  The syntax is: CASE word_desc IN pattern_list ESAC.
  787.    The pattern_list is a linked list of pattern clauses; each clause contains
  788.    some patterns to compare word_desc against, and an associated command to
  789.    execute. */
  790. execute_case_command (case_command)
  791.      CASE_COM *case_command;
  792. {
  793.   extern dispose_words ();
  794.   WORD_LIST *wlist = expand_word (case_command->word, 0);
  795.   PATTERN_LIST *clauses = case_command->clauses;
  796.   register WORD_LIST *list;
  797.   int retval = EXECUTION_SUCCESS;
  798.   char *word = (wlist) ? wlist->word->word : "";
  799.  
  800.   add_unwind_protect (dispose_words, wlist);
  801.   while (clauses)
  802.     {
  803.       QUIT;
  804.       list = clauses->patterns;
  805.       while (list)
  806.     {
  807.       WORD_LIST *es = expand_word (list->word, 0);
  808.       char *pattern = (es) ? es->word->word : "";
  809.  
  810.       if (glob_match (pattern, word, 0))
  811.         {
  812.           dispose_words (es);
  813.           execute_command (clauses->action);
  814.           retval = last_command_exit_value;
  815.           goto exit_command;
  816.         }
  817.       dispose_words (es);
  818.       list = list->next;
  819.       QUIT;
  820.     }
  821.       clauses = clauses->next;
  822.     }
  823.  exit_command:
  824.   remove_unwind_protect ();
  825.   dispose_words (wlist);
  826.   return (retval);
  827. }
  828.  
  829. /* The WHILE command.  Syntax: WHILE test DO action; DONE.
  830.    Repeatedly execute action while executing test produces
  831.    EXECUTION_SUCCESS. */
  832. execute_while_command (while_command)
  833.      WHILE_COM *while_command;
  834. {
  835.   extern int breaking;
  836.   extern int continuing;
  837.   int commands_executed = 0;
  838.   int old_error_exit = exit_immediately_on_error, return_value;
  839.  
  840.   loop_level++;
  841.   while (1)
  842.     {
  843.       exit_immediately_on_error = 0;
  844.       return_value = execute_command (while_command->test);
  845.       exit_immediately_on_error += old_error_exit;
  846.       if (return_value != EXECUTION_SUCCESS)
  847.     break;
  848.       QUIT;
  849.       commands_executed = 1;
  850.       execute_command (while_command->action);
  851.       QUIT;
  852.  
  853.       if (breaking)
  854.     {
  855.       breaking--;
  856.       break;
  857.     }
  858.  
  859.       if (continuing)
  860.     {
  861.       continuing--;
  862.       if (continuing)
  863.         break;
  864.     }
  865.       exit_immediately_on_error = 0;
  866.     }
  867.   loop_level--;
  868.   return ((commands_executed == 1) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
  869. }
  870.  
  871. /* UNTIL is just like WHILE except that the test result is negated. */
  872. execute_until_command (while_command)
  873.      WHILE_COM *while_command;
  874. {
  875.   extern int breaking;
  876.   extern int continuing;
  877.   int commands_executed = 0;
  878.   int old_error_exit = exit_immediately_on_error, return_value;
  879.  
  880.   loop_level++;
  881.   while (1)
  882.     {
  883.       exit_immediately_on_error = 0;
  884.       return_value = execute_command (while_command->test);
  885.       exit_immediately_on_error += old_error_exit;
  886.       if (return_value == EXECUTION_SUCCESS)
  887.     break;
  888.       QUIT;
  889.       commands_executed = 1;
  890.       execute_command (while_command->action);
  891.       QUIT;
  892.  
  893.       if (breaking)
  894.     {
  895.       breaking--;
  896.       break;
  897.     }
  898.  
  899.       if (continuing)
  900.     {
  901.       continuing--;
  902.       if (continuing)
  903.         break;
  904.     }
  905.     }
  906.   loop_level--;
  907.   return (commands_executed);
  908. }
  909.  
  910. /* IF test THEN command [ELSE command].
  911.    IF also allows ELIF in the place of ELSE IF, but
  912.    the parser makes *that* stupidity transparent. */
  913. execute_if_command (if_command)
  914.      IF_COM *if_command;
  915. {
  916.   int old_error_exit = exit_immediately_on_error, return_value;
  917.  
  918.   exit_immediately_on_error = 0;
  919.   return_value = execute_command (if_command->test);
  920.   exit_immediately_on_error += old_error_exit;
  921.  
  922.   if (return_value == EXECUTION_SUCCESS)
  923.     {
  924.       QUIT;
  925.       return (execute_command (if_command->true_case));
  926.     }
  927.   else
  928.     {
  929.       QUIT;
  930.       return (execute_command (if_command->false_case));
  931.     }
  932. }
  933.  
  934. Function *
  935. find_shell_builtin (string)
  936.      char *string;
  937. {
  938.   int i = 0;
  939.   while (shell_builtins[i].name)
  940.     {
  941.       if (shell_builtins[i].enabled &&
  942.       (STREQ (shell_builtins[i].name, string)))
  943.     return (shell_builtins[i].function);
  944.       i++;
  945.     }
  946.   return ((Function *)NULL);
  947. }
  948.  
  949. #ifdef NOTYET
  950. /*
  951.  * restore fd to the standard input
  952.  */
  953. static int
  954. restore_stdin (fd)
  955.      int fd;
  956. {
  957.   if (dup2 (fd, 0) < 0)
  958.     perror("restore_stdin: dup2:");
  959.   close (fd);
  960.   return (0);
  961. }
  962. #endif /* NOTYET */
  963.  
  964. /* The name of the command that is currently being executed.
  965.    `test' needs this, for example. */
  966. char *this_command_name;
  967. /* The last argument to the previous command, used for $_ */
  968. char *lastarg = (char *)NULL;
  969.  
  970. bind_lastarg (arg)
  971.      char *arg;
  972. {
  973.   SHELL_VAR *var;
  974.  
  975.   if (!arg)
  976.     arg = "";
  977.   var = bind_variable ("_", arg);
  978.   var->attributes &= ~att_exported;
  979. }
  980.  
  981. /* For catching RETURN in a function. */
  982. int return_catch_flag = 0;
  983. int return_catch_value;
  984. jmp_buf return_catch;
  985.  
  986. /* The meaty part of all the executions.  We have to start hacking the
  987.    real execution of commands here.  Fork a process, set things up,
  988.    execute the command. */
  989. execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
  990.      SIMPLE_COM *simple_command;
  991.      int pipe_in, pipe_out;
  992.      struct fd_bitmap *fds_to_close;
  993. {
  994.   WORD_LIST *expand_words (), *copy_word_list ();
  995.   WORD_LIST *words, *lastword;
  996.  
  997.   /* Remember what this command line looks like at invocation. */
  998.   extern int command_string_index, variable_context, line_number;
  999.   extern int ignore_function_references;
  1000.   extern char *the_printed_command;
  1001.   char *command_line;
  1002.   int first_word_quoted;
  1003.  
  1004.  
  1005.  
  1006.   /* If we're in a function, update the pseudo-line-number information. */
  1007.   if (variable_context)
  1008.     line_number++;
  1009.  
  1010.   command_string_index = 0;
  1011.   print_simple_command (simple_command);    /* expensive for scripts... */
  1012.   command_line = (char *)alloca (1 + strlen (the_printed_command));
  1013.   strcpy (command_line, the_printed_command);
  1014.  
  1015.   first_word_quoted =
  1016.     (simple_command->words? simple_command->words->word->quoted : 0);
  1017.  
  1018.   /* If we are re-running this as the result of a command substitution, do
  1019.      not expand the command words a second time. */
  1020.   if (!ignore_function_references)
  1021.     words = expand_words (simple_command->words);
  1022.   else
  1023.     words = copy_word_list (simple_command->words);
  1024.  
  1025.   /* It is possible for WORDS not to have anything left in it.
  1026.      Perhaps all the words consisted of `$foo', and there was
  1027.      no variable `$foo'. */
  1028.   if (words)
  1029.     {
  1030.       extern Function *last_shell_builtin, *this_shell_builtin;
  1031.       extern int ignore_function_references;
  1032.       Function *builtin;
  1033.       SHELL_VAR *var = find_function (words->word->word);
  1034.       char *auto_resume_value;
  1035.  
  1036.       if (echo_command_at_execute)
  1037.     {
  1038.       extern char *string_list (), *indirection_level_string ();
  1039.       char *line = string_list (words);
  1040.  
  1041.       if (line && *line)
  1042.         fprintf (stderr, "%s%s\n", indirection_level_string (), line);
  1043.  
  1044.       if (line)
  1045.         free (line);
  1046.     }
  1047.  
  1048.       if (ignore_function_references)
  1049.     var = (SHELL_VAR *)NULL;
  1050.  
  1051.       QUIT;
  1052.  
  1053.       /* 
  1054.        * Save the last word in this command, to bind to "$_" after execution.
  1055.        */
  1056.       for (lastword = words; lastword->next; lastword = lastword->next)
  1057.     ;
  1058.       lastarg = lastword->word->word;
  1059.  
  1060. #ifdef JOB_CONTROL
  1061.       /* Is this command a job control related thing? */
  1062.       if (words->word->word[0] == '%')
  1063.     {
  1064.       int r;
  1065.  
  1066.       if (async)
  1067.         {
  1068.           this_command_name = "bg";
  1069.           r = bg_builtin (words);
  1070.         }
  1071.       else
  1072.         {
  1073.           this_command_name = "fg";
  1074.           r =  fg_builtin (words);
  1075.         }
  1076.       bind_lastarg (lastarg);
  1077.       return r;
  1078.     }
  1079.  
  1080.       /* One other possiblilty.  The user may want to resume an existing job.
  1081.      If they do, find out whether this word is a candidate for a running
  1082.      job. */
  1083.       if ((auto_resume_value = get_string_value ("auto_resume")) &&
  1084.       !first_word_quoted &&
  1085.       !words->next &&
  1086.       words->word->word[0] &&
  1087.       !simple_command->redirects &&
  1088.       pipe_in == NO_PIPE &&
  1089.       pipe_out == NO_PIPE &&
  1090.       !async)
  1091.     {
  1092.       char *word = words->word->word;
  1093.       register int i, wl = strlen (word), exact;
  1094.  
  1095.       exact = strcmp (auto_resume_value, "exact") == 0;
  1096.       for (i = job_slots - 1; i > -1; i--)
  1097.         {
  1098.           if (jobs[i])
  1099.         {
  1100.           register PROCESS *p = jobs[i]->pipe;
  1101.           do
  1102.             {
  1103.               if ((JOBSTATE (i) == JSTOPPED) &&
  1104.               (strncmp (p->command, word,
  1105.                     exact ? strlen (p->command) : wl) == 0))
  1106.             {
  1107.               dispose_words (words);
  1108.               return (start_job (i, 1));
  1109.             }
  1110.               p = p->next;
  1111.             }
  1112.           while (p != jobs[i]->pipe);
  1113.         }
  1114.         }
  1115.     }
  1116. #endif
  1117.  
  1118.       /* Remember the name of this command globally. */
  1119.       this_command_name = words->word->word;
  1120.  
  1121.       /* Not a running job.  Do normal command processing. */
  1122.       maybe_make_export_env ();
  1123.       QUIT;
  1124.       run_pending_traps ();    /* XXX */
  1125.  
  1126.       /* This command could be a shell builtin or a user-defined function.
  1127.      If so, and we have pipes, then fork a subshell in here.  Else, just
  1128.      do the command. */
  1129.  
  1130.       if (var)
  1131.     builtin = (Function *)NULL;
  1132.       else
  1133.     {
  1134.       builtin = find_shell_builtin (words->word->word);
  1135.       if (builtin)
  1136.         {
  1137.           if (this_shell_builtin)
  1138.         last_shell_builtin = this_shell_builtin;
  1139.           this_shell_builtin = builtin;
  1140.         }
  1141.     }
  1142.  
  1143.       if (builtin || var)
  1144.     {
  1145.       put_command_name_into_env (this_command_name);
  1146.       if ((pipe_in != NO_PIPE) || (pipe_out != NO_PIPE) || async)
  1147.         {
  1148.           if (make_child (savestring (command_line), async) == 0)
  1149.         {
  1150. #ifdef JOB_CONTROL
  1151.           /* Eradicate all traces of job control after we fork
  1152.              the subshell, so all jobs begun by this subshell are
  1153.              in the same process group as the shell itself. */
  1154.  
  1155.           /* Allow the output of `jobs' to be piped. */
  1156.           if (builtin == jobs_builtin && !async &&
  1157.               pipe_out != NO_PIPE && pipe_in != NO_PIPE)
  1158.             kill_current_pipeline ();
  1159.           else
  1160.             without_job_control ();
  1161. #endif /* JOB_CONTROL */
  1162.  
  1163.           /* A subshell is neither a login shell nor interactive. */
  1164.           login_shell = interactive = 0;    /* XXX */
  1165.  
  1166.           do_piping (pipe_in, pipe_out);
  1167.  
  1168.           if (fds_to_close)
  1169.             close_fd_bitmap (fds_to_close);
  1170.             
  1171.           if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1172.             {
  1173.               if (builtin)
  1174.             {
  1175.               int result;
  1176.               extern jmp_buf top_level;
  1177.  
  1178.               /* Save the values of pipe_in and pipe_out for
  1179.                  possible later use by parse_and_execute (). */
  1180.               builtin_pipe_in = pipe_in;
  1181.               builtin_pipe_out = pipe_out;
  1182.  
  1183.               /* Give builtins a place to jump back to on failure,
  1184.                  so we don't go back up to main(). */
  1185.               if (result = setjmp (top_level))
  1186.                 exit (result);  
  1187.               exit ((*builtin) (words->next));
  1188.             }
  1189.               else
  1190.             {
  1191.               COMMAND *fc, *tc = (COMMAND *)function_cell (var);
  1192.               int result;
  1193.               extern int variable_context, line_number;
  1194.  
  1195.               remember_args (words->next, 1);
  1196.               line_number = 0;
  1197. #ifdef JOB_CONTROL
  1198.               stop_pipeline (async, (COMMAND *)NULL);
  1199. #endif
  1200.               variable_context++;
  1201.               return_catch_flag++;
  1202.  
  1203.               /* We can do this because function bodies are always
  1204.                  guaranteed to be group commands, according to the
  1205.                  grammar in parse.y.  If we don't do this now,
  1206.                  execute_command_internal will graciously fork
  1207.                  another subshell for us, and we'll lose contact
  1208.                  with the rest of the pipeline and fail to get
  1209.                  any SIGPIPE that might be sent. */
  1210.  
  1211.               if (tc->type == cm_group)
  1212.                 fc = (COMMAND *)
  1213.                   copy_command (tc->value.Group->command);
  1214.               else
  1215.                 fc = (COMMAND *)copy_command (tc);
  1216.  
  1217.               /* result = execute_command (fc); doesn't work.
  1218.                  We need to explicitly specify the pipes in
  1219.                  and out so that they are closed in all the
  1220.                  processes that rely on their being closed.  If
  1221.                  they are not, it is possible to not get the
  1222.                  SIGPIPE that we need to kill all the processes
  1223.                  sharing the pipe. */
  1224.               result = execute_command_internal
  1225.                 (fc, 0, pipe_in, pipe_out, fds_to_close);
  1226.  
  1227.               dispose_command (fc);
  1228.               variable_context--;
  1229.  
  1230.               exit (result);
  1231.             }
  1232.             }
  1233.           else
  1234.             {
  1235.               exit (EXECUTION_FAILURE);
  1236.             }
  1237.         }
  1238.           else
  1239.         {
  1240.           close_pipes (pipe_in, pipe_out);
  1241.           bind_lastarg (lastarg);
  1242.           return (EXECUTION_SUCCESS);
  1243.         }
  1244.         }
  1245.       else
  1246.         {
  1247.           int result = EXECUTION_FAILURE;
  1248.           int redir_result;
  1249.  
  1250. #if defined (RIGIDLY_POSIX_COMPLIANT)
  1251.           if (builtin && builtin == exec_builtin)
  1252.         redir_result = do_redirections (simple_command->redirects,
  1253.                         1, 1, 1);
  1254.           else
  1255. #endif /* RIGIDLY_POSIX_COMPLIANT */
  1256.         redir_result = do_redirections (simple_command->redirects,
  1257.                         1, 1, 0);
  1258.  
  1259.           if (redir_result == 0)
  1260.         {
  1261.           REDIRECT *saved_undo_list = redirection_undo_list;
  1262.  
  1263.           /* Calling the "exec" builtin changes redirections
  1264.              forever. */
  1265.           if (builtin == exec_builtin)
  1266.             {
  1267.               dispose_redirects (saved_undo_list);
  1268.               saved_undo_list = (REDIRECT *)NULL;
  1269.             }
  1270.           else
  1271.             {
  1272.               begin_unwind_frame ("saved redirects");
  1273.               add_unwind_protect (cleanup_func_redirects, (char *)saved_undo_list);
  1274.             }
  1275.  
  1276.           redirection_undo_list = (REDIRECT *)NULL;
  1277.  
  1278.           if (builtin)
  1279.             result = ((*builtin) (words->next));
  1280.           else
  1281.             {
  1282.               int return_val;
  1283.               extern int dispose_command (), pop_context ();
  1284.               jmp_buf old_return_catch;
  1285.               COMMAND *tc;
  1286.               extern int line_number;
  1287.  
  1288.               tc = (COMMAND *)copy_command (function_cell (var));
  1289.  
  1290.               push_context ();
  1291.               begin_unwind_frame ("function_calling");
  1292.               add_unwind_protect (pop_context, (char *)NULL);
  1293.               add_unwind_protect (dispose_command, (char *)tc);
  1294.  
  1295.               /* Note the second argument of "1", meaning that
  1296.              we discard the current value of "$*"!  This
  1297.              is apparently the right thing. */
  1298.               remember_args (words->next, 1);
  1299.  
  1300.               line_number = 0;
  1301.               return_catch_flag++;
  1302.               bcopy ((char *)return_catch, (char *)old_return_catch,
  1303.                  sizeof (jmp_buf));
  1304.               return_val =  setjmp (return_catch);
  1305.  
  1306.               if (return_val)
  1307.             result = return_catch_value;
  1308.               else
  1309.             result = execute_command_internal (tc, 0,
  1310.                     NO_PIPE, NO_PIPE, fds_to_close);
  1311.  
  1312.               run_unwind_frame ("function_calling");
  1313.               return_catch_flag--;
  1314.               bcopy ((char *)old_return_catch, (char *)return_catch,
  1315.                  sizeof (jmp_buf));
  1316.             }
  1317.           redirection_undo_list = saved_undo_list;
  1318.           discard_unwind_frame ("saved redirects");
  1319.         }
  1320.           do_redirections (redirection_undo_list, 1, 0, 0);
  1321.           bind_lastarg (lastarg);
  1322.           dispose_words (words);
  1323.           run_pending_traps ();    /* XXX */
  1324.           return (result);
  1325.         }
  1326.     }
  1327.  
  1328.       {
  1329.     /* Hopefully this command is defined in a disk file somewhere.
  1330.        
  1331.        1) fork ()
  1332.        2) connect pipes
  1333.        3) close file descriptors 3-NOFILE    XXX - not anymore...
  1334.        4) look up the command
  1335.        5) do redirections
  1336.        6) execve ()
  1337.        7) If the execve failed, see if the file has executable mode set.
  1338.        If so, and it isn't a directory, then execute its contents as
  1339.        a shell script.
  1340.        
  1341.        Note that the filename hashing stuff has to take place up here,
  1342.        in the parent.  This is probably why the Bourne style shells
  1343.        don't handle it, since that would require them to go through
  1344.        this gnarly hair, for no good reason.
  1345.        */
  1346.  
  1347.     char **make_word_array (), *find_user_command (),
  1348.     *find_hashed_filename ();
  1349.  
  1350.     char *hashed_file = (char *)NULL, *command, **args;
  1351.  
  1352.     /* Don't waste time trying to find hashed data for a pathname
  1353.        that is already completely specified. */
  1354.  
  1355.     if (!absolute_program (words->word->word))
  1356.       hashed_file = find_hashed_filename (words->word->word);
  1357.         
  1358.     if (hashed_file)
  1359.       command = savestring (hashed_file);
  1360.     else
  1361.       { if (absolute_program (words->word->word))
  1362.               { 
  1363. /** 
  1364.  ** (sjk)++ Add checking of extensions {.tos/.ttp/.prg} on absolute
  1365.  **         paths on the Atari ST.
  1366.  **/
  1367. #if defined(atarist)
  1368.         char *name_suffix = alloca(4 + strlen(words->word->word));
  1369.                 struct stat finfo;
  1370.                 strcpy(name_suffix,words->word->word);
  1371.                   if (0 != stat(name_suffix,&finfo))
  1372.                  { strcat(name_suffix,".tos");
  1373.                        if (0 != stat(name_suffix,&finfo)) 
  1374.                           { strcpy(name_suffix,words->word->word);
  1375.                             strcat(name_suffix,".ttp");
  1376.                             if (0 != stat(name_suffix,&finfo)) 
  1377.                        { strcpy(name_suffix,words->word->word);
  1378.                                  strcat(name_suffix,".prg");
  1379.                                  if (0 != stat(name_suffix,&finfo))
  1380.                                     strcpy(name_suffix,words->word->word);
  1381.                    }
  1382.               }
  1383.              }
  1384.                      command = savestring (name_suffix);
  1385. #else
  1386.               command = savestring (words->word->word);
  1387. #endif
  1388.           }
  1389.         else
  1390.           command = find_user_command (words->word->word);
  1391.         if (command && !hashing_disabled)
  1392.           {
  1393.         extern int dot_found_in_search;
  1394.         if (!absolute_program (words->word->word))
  1395.           remember_filename (words->word->word,
  1396.                      command, dot_found_in_search);
  1397.         /* Increase the number of hits to 1. */
  1398.         find_hashed_filename (words->word->word);
  1399.           }
  1400.       }
  1401.  
  1402.     if (command)
  1403.       put_command_name_into_env (command);
  1404.  
  1405.     /* We have to make the child before we check for the non-existance
  1406.        of COMMAND, since we want the error messages to be redirected. */
  1407.       
  1408.     if (make_child (savestring (command_line), async) == 0)
  1409.       { 
  1410.             do_piping (pipe_in, pipe_out);
  1411.  
  1412.         /* Execve expects the command name to be in args[0].  So we
  1413.            leave it there, in the same format that the user used to
  1414.            type it in. */
  1415.         args = make_word_array (words);
  1416.  
  1417.         if (!command)
  1418.           {
  1419.         report_error ("%s: command not found", args[0]);
  1420.         exit (EXECUTION_FAILURE);
  1421.           }
  1422.  
  1423.         /* This functionality is now provided by close-on-exec of the
  1424.            file descriptors manipulated by redirection and piping.
  1425.            Some file descriptors still need to be closed in all children
  1426.            because of the way bash does pipes; fds_to_close is a 
  1427.            bitmap of all such file descriptors. */
  1428.         if (fds_to_close)
  1429.           close_fd_bitmap (fds_to_close);
  1430.  
  1431.         if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1432.           {
  1433.         signal (SIGCHLD, SIG_DFL);
  1434.         execve (command, args, export_env);
  1435.  
  1436.         /* If we get to this point, then start checking out the file.
  1437.            Maybe it is something we can hack ourselves. */
  1438.         {
  1439.           struct stat finfo;
  1440.           extern int errno;
  1441.  
  1442.           if (errno != ENOEXEC)
  1443.             {
  1444.               if ((stat (command, &finfo) == 0) &&
  1445.               (S_ISDIR (finfo.st_mode)))
  1446.             report_error ("%s: is a directory", args[0]);
  1447.               else
  1448.             file_error (command);
  1449.         
  1450.               exit (EXECUTION_FAILURE);
  1451.             }
  1452.           else
  1453.             {
  1454.               /* This file is executable.
  1455.              If it begins with #!, then help out people
  1456.              with losing operating systems.  Otherwise,
  1457.              check to see if it is a binary file by seeing
  1458.              if the first line (or up to 30 characters) are
  1459.              in the ASCII set.
  1460.              Execute the contents as shell commands. */
  1461.               extern char *shell_name;
  1462.               int larry = array_len (args) + 1;
  1463.               int i, should_exec = 0;
  1464.  
  1465.               {
  1466.             int fd = open (command, O_RDONLY);
  1467.             if (fd != -1)
  1468.               {
  1469.                 unsigned char sample[80];
  1470.                 int sample_len = read (fd, &sample[0], 80);
  1471.  
  1472.                 /* Is this supposed to be an executable script? */
  1473.                 if (strncmp (sample, "#!", 2) == 0)
  1474.                   {
  1475.                 char *execname;
  1476.                 int start;
  1477.  
  1478.                 for (i = 2;
  1479.                      whitespace (sample[i]) && i < sample_len;
  1480.                      i++);
  1481.                 start = i;
  1482.                 for (; !whitespace (sample[i]) &&
  1483.                      sample[i] != '\n' && i < sample_len;
  1484.                      i++);
  1485.  
  1486.                 execname = (char *)xmalloc (1 + (i - start));
  1487.                 strncpy (execname, sample + start, i - start);
  1488.                 execname[i - start] = '\0';
  1489.  
  1490.                 should_exec = 1;
  1491.                 shell_name = execname;
  1492.                   }
  1493. #if defined (HAVE_CSH)
  1494.                 /* If this system has Csh, then keep the old
  1495.                    BSD semantics. */
  1496.                 else if (sample_len > 0 && sample[0] == '#')
  1497.                   {
  1498.                 /* Scripts starting with a # are for Csh. */
  1499.                 shell_name = savestring ("/bin/csh");
  1500.                 should_exec = 1;
  1501.                   }
  1502. #endif /* HAVE_CSH */
  1503.                 else
  1504.                   {
  1505.                 if (sample_len != -1)
  1506.                   if (check_binary_file (sample, sample_len))
  1507.                     {
  1508.                       report_error
  1509.                     ("%s: cannot execute binary file",
  1510.                      command);
  1511.                       exit (EX_BINARY_FILE);
  1512.                     }
  1513.                   }
  1514.                 close (fd);
  1515.               }
  1516.               }
  1517. #ifdef JOB_CONTROL
  1518.               /* Forget about the way that job control was working.
  1519.              We are in a subshell. */
  1520.               without_job_control ();
  1521. #endif
  1522. #ifdef ALIAS
  1523.               /* Forget about any aliases that we knew of.
  1524.              We are in a subshell. */
  1525.               delete_all_aliases ();
  1526. #endif
  1527.               /* Insert the name of this shell into the
  1528.              argument list. */
  1529.               args =
  1530.             (char **)xrealloc ((char *)args, (1 + larry) * sizeof (char *));
  1531.               for (i = larry - 1; i; i--)
  1532.             args[i] = args[i - 1];
  1533.  
  1534.               args[0] = shell_name;
  1535.               args[1] = command;
  1536.               args[larry] = (char *)NULL;
  1537.  
  1538.               if (args[0][0] == '-')
  1539.             args[0]++;
  1540.  
  1541.               if (should_exec)
  1542.             {
  1543.               struct stat finfo;
  1544.               extern int errno;
  1545.  
  1546.               execve (shell_name, args, export_env);
  1547.  
  1548.               /* Oh, no!  We couldn't even exec this! */
  1549.               if ((stat (shell_name, &finfo) == 0) &&
  1550.                   (S_ISDIR (finfo.st_mode)))
  1551.                 report_error ("%s: is a directory", args[0]);
  1552.               else
  1553.                 file_error (shell_name);
  1554.  
  1555.               exit (EXECUTION_FAILURE);
  1556.             }
  1557.               else
  1558.             {
  1559.               /* This doesn't seem to work on Ultrix 3.1
  1560.                  when executing scripts like this from
  1561.                  the .profile */
  1562.               extern jmp_buf subshell_top_level;
  1563.               extern int subshell_argc;
  1564.               extern char **subshell_argv;
  1565.               extern char **subshell_envp;
  1566.  
  1567.               subshell_argc = larry;
  1568.               subshell_argv = args;
  1569.               subshell_envp = export_env;
  1570.               longjmp (subshell_top_level, 1);
  1571.             }
  1572.             }
  1573.         }
  1574.           }
  1575.         else
  1576.           {
  1577.         exit (EXECUTION_FAILURE);
  1578.           }
  1579.       }
  1580.     
  1581.     else
  1582.       { /* Make sure that the pipes are closed in the parent. */
  1583.       
  1584. /**
  1585.  ** On the Atari ST force GEMDOS buffers into RTL buffers.
  1586.  **/      
  1587. #if defined(atarist)
  1588.             flush_key_buff(fileno(stdin));
  1589. #endif
  1590.         close_pipes (pipe_in, pipe_out);
  1591.         if (command)
  1592.           free (command);
  1593.       }
  1594.       }
  1595.       dispose_words (words);
  1596.       bind_lastarg (lastarg);
  1597.       return (EXECUTION_SUCCESS);
  1598.     }
  1599.   else if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
  1600.     {
  1601.       /* We have a null command, but we really want a subshell to take
  1602.      care of it.  Just fork, do piping and redirections, and exit. */
  1603.       if (make_child (savestring (""), async) == 0)
  1604.     {
  1605.       do_piping (pipe_in, pipe_out);
  1606.  
  1607.       if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1608.         exit (EXECUTION_SUCCESS);
  1609.       else
  1610.         exit (EXECUTION_FAILURE);
  1611.     }
  1612.       else
  1613.     {
  1614.       bind_lastarg ("");
  1615.       close_pipes (pipe_in, pipe_out);
  1616.       return (EXECUTION_SUCCESS);
  1617.     }
  1618.     }
  1619.   else
  1620.     {
  1621.       /* Even if there aren't any command names, pretend to do the
  1622.      redirections that are specified.  The user expects the side
  1623.      effects to take place. */
  1624.       bind_lastarg ("");
  1625.       if (do_redirections (simple_command->redirects, 0, 0, 0) == 0)
  1626.     return (last_command_exit_value);
  1627.       else
  1628.     return (EXECUTION_FAILURE);
  1629.     }
  1630. }
  1631.  
  1632. close_all_files ()
  1633. {
  1634.   register int i, fd_table_size;
  1635.  
  1636.   fd_table_size = getdtablesize ();
  1637.  
  1638.   for (i = 3; i < fd_table_size; i++)
  1639.     close (i);
  1640. }
  1641.  
  1642. close_pipes (in, out)
  1643.      int in, out;
  1644. {
  1645.   if (in >= 0) close (in);
  1646.   if (out >= 0) close (out);
  1647. }
  1648.     
  1649.  
  1650. /* Redirect input and output to be from and to the specified pipes.
  1651.    NO_PIPE and REDIRECT_BOTH are handled correctly. */
  1652. do_piping (pipe_in, pipe_out)
  1653.      int pipe_in, pipe_out;
  1654. { int res;
  1655.  
  1656.   if (pipe_in != NO_PIPE)
  1657.     {
  1658.       res = dup2 (pipe_in, 0);
  1659.       if (res < 0) 
  1660.         fprintf(stderr,"pipe_in - dup2:%d, errno:%d\n",res,errno);
  1661. #if !defined(atarist)
  1662.       close (pipe_in);
  1663. #endif
  1664.     }
  1665.   if (pipe_out != NO_PIPE)
  1666.     {
  1667.       res = dup2 (pipe_out, 1);
  1668.       if (res < 0)  
  1669.         fprintf(stderr,"pipe_in - dup2:%d, errno:%d\n",res,errno);
  1670. #if !defined(atarist)
  1671.       close (pipe_out);
  1672. #endif
  1673.       if (pipe_out == REDIRECT_BOTH)
  1674.     dup2 (1, 2);
  1675.     }
  1676. }
  1677.  
  1678. /* Defined in flags.c.  Non-zero means don't overwrite existing files. */
  1679. extern int noclobber;
  1680.  
  1681. #define AMBIGUOUS_REDIRECT -1
  1682. #define NOCLOBBER_REDIRECT -2
  1683. /* Perform the redirections on LIST.  If FOR_REAL, then actually make
  1684.    input and output file descriptors, otherwise just do whatever is
  1685.    neccessary for side effecting.  INTERNAL says to remember how to
  1686.    undo the redirections later, if non-zero.  If SET_CLEXEC is non-zero,
  1687.    file descriptors opened in do_redirection() have their close-on-exec
  1688.    flag set. */
  1689. do_redirections (list, for_real, internal, set_clexec)
  1690.      REDIRECT *list;
  1691.      int for_real, internal;
  1692. {
  1693.   register int error;
  1694.   register REDIRECT *temp = list;
  1695.  
  1696.   if (internal && redirection_undo_list)
  1697.     {
  1698.       dispose_redirects (redirection_undo_list);
  1699.       redirection_undo_list = (REDIRECT *)NULL;
  1700.     }
  1701.  
  1702.   while (temp)
  1703.     {
  1704.       extern char *strerror ();    /* in misc.c */
  1705.  
  1706.       error = do_redirection (temp, for_real, internal, set_clexec);
  1707.       if (error)
  1708.     {
  1709.       if (error == AMBIGUOUS_REDIRECT)
  1710.         report_error ("%s: Ambiguous redirect",
  1711.              temp->redirectee.filename->word);
  1712.       else if (error == NOCLOBBER_REDIRECT)
  1713.         report_error ("%s: Cannot clobber existing file",
  1714.               temp->redirectee.filename->word);
  1715.       else
  1716.         report_error ("%s: %s",
  1717.              temp->redirectee.filename->word,
  1718.              strerror(error));
  1719.       return (error);
  1720.     }
  1721.  
  1722.       temp = temp->next;
  1723.     }
  1724.   return (0);
  1725. }
  1726.  
  1727.  
  1728. /* Expand the word in WORD returning a string.  If WORD expands to
  1729.    multiple words (or no words), then return NULL. */
  1730. char *
  1731. redirection_expand (word)
  1732.      WORD_DESC *word;
  1733. {
  1734.   char *string_list (), *result;
  1735.   WORD_LIST *make_word_list (), *expand_words_no_vars ();
  1736.   WORD_LIST *tlist1, *tlist2;
  1737.  
  1738.   tlist1 = make_word_list (copy_word (word), (WORD_LIST *)NULL);
  1739.   tlist2 = expand_words_no_vars (tlist1);
  1740.   dispose_words (tlist1);
  1741.  
  1742.   if (!tlist2 || tlist2->next)
  1743.     {
  1744.       /* We expanded to no words, or to more than a single word.
  1745.      Dispose of the word list and return NULL. */
  1746.       if (tlist2)
  1747.     dispose_words (tlist2);
  1748.       return ((char *)NULL);
  1749.     }
  1750.   result = string_list (tlist2);
  1751.   dispose_words (tlist2);
  1752.   return (result);
  1753. }
  1754.  
  1755. /* Do the specific redirection requested.  Returns errno in case of error.
  1756.    If FOR_REAL is zero, then just do whatever is neccessary to produce the
  1757.    appropriate side effects.   REMEMBERING, if non-zero, says to remember
  1758.    how to undo each redirection.  If SET_CLEXEC is non-zero, then
  1759.    we set all file descriptors > 2 that we open to be close-on-exec.  */
  1760. do_redirection (redirect, for_real, remembering, set_clexec)
  1761.      REDIRECT *redirect;
  1762.      int for_real, remembering;
  1763. {
  1764.   WORD_DESC *redirectee = redirect->redirectee.filename;
  1765.   int redirector = redirect->redirector;
  1766.   char *redirectee_word = 0;
  1767.   enum r_instruction ri = redirect->instruction;
  1768.  
  1769.   int fd;
  1770.  
  1771.   switch (ri)
  1772.     {
  1773.     case r_output_direction:
  1774.     case r_appending_to:
  1775.     case r_input_direction:
  1776.     case r_inputa_direction:
  1777.     case r_err_and_out:        /* command &>filename */
  1778.     case r_input_output:
  1779.     case r_output_force:
  1780.  
  1781.       if (!(redirectee_word = redirection_expand (redirectee)))
  1782.     return (AMBIGUOUS_REDIRECT);
  1783.  
  1784.       /* If we are in noclobber mode, you are not allowed to overwrite
  1785.        existing files.  Check first. */
  1786.       if (noclobber && (ri == r_output_direction ||
  1787.               ri == r_input_output ||
  1788.               ri == r_err_and_out))
  1789.       {
  1790.     struct stat buf;
  1791.     if ((stat (redirectee_word, &buf) == 0) &&
  1792.         (S_ISREG (buf.st_mode)))
  1793.       return (NOCLOBBER_REDIRECT);
  1794.       }
  1795.  
  1796.       fd = open (redirectee_word, redirect->flags, 0666);
  1797.       free (redirectee_word);
  1798.  
  1799.       if (fd < 0 )
  1800.     return (errno);
  1801.  
  1802.       if (for_real)
  1803.     {
  1804.       if (remembering)
  1805.         /* Only setup to undo it if the thing to undo is active. */
  1806.         if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
  1807.           add_undo_redirect (redirector);
  1808.         else
  1809.           add_undo_close_redirect (redirector);
  1810.  
  1811.       if ((fd != redirector) && (dup2 (fd, redirector) < 0))
  1812.         return (errno);
  1813.  
  1814.       /*
  1815.        * If we're remembering, then this is the result of a while, for
  1816.        * or until loop with a loop redirection, or a function/builtin
  1817.        * executing in the parent shell with a redirection.  In the
  1818.        * function/builtin case, we want to set all file descriptors > 2
  1819.        * to be close-on-exec to duplicate the effect of the old
  1820.        * for i = 3 to NOFILE close(i) loop.  In the case of the loops,
  1821.        * both sh and ksh leave the file descriptors open across execs.
  1822.        * The Posix standard mentions only the exec builtin.
  1823.        */
  1824.       if (set_clexec && (redirector > 2))
  1825.         SET_CLOSE_ON_EXEC (redirector);
  1826.     }
  1827.       if (fd != redirector)
  1828.     close (fd);        /* don't close what we just opened! */
  1829.  
  1830.       /* If we are hacking both stdout and stderr, do the stderr
  1831.      redirection here. */
  1832.       if (redirect->instruction == r_err_and_out)
  1833.     {
  1834.       if (for_real)
  1835.         {
  1836.           if (remembering)
  1837.         add_undo_redirect (2);
  1838.           dup2 (1, 2);
  1839.         }
  1840.     }
  1841.       break;
  1842.  
  1843.     case r_reading_until:
  1844.     case r_deblank_reading_until:
  1845.       {
  1846.     /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
  1847.        the new input.  Place it in a temporary file. */
  1848.     char *document = (char *)NULL;
  1849.     int document_index = 0;
  1850.  
  1851.     /* Expand the text if the word that was specified had no quoting.
  1852.        Note that the text that we expand is treated exactly as if it
  1853.        were surrounded by double-quotes.  */
  1854.     
  1855.     if (!redirectee)
  1856.       document = savestring ("");
  1857.     else
  1858.       {
  1859.         if (!redirectee->quoted)
  1860.           {
  1861.         WORD_LIST *temp_word_list =
  1862.           (WORD_LIST *)expand_string (redirectee->word,
  1863.                           Q_HERE_DOCUMENT);
  1864.  
  1865.         document = (char *)string_list (temp_word_list);
  1866.         if (!document)
  1867.           document = savestring ("");
  1868.         dispose_words (temp_word_list);
  1869.           }
  1870.         else
  1871.           {
  1872.         document = redirectee->word;
  1873.           }
  1874.         document_index = strlen (document);
  1875.  
  1876.         {
  1877.           char filename[40];
  1878.           int pid = getpid ();
  1879.  
  1880.           /* Make the filename for the temp file. */
  1881.           sprintf (filename, "/tmp/t%d-sh", pid);
  1882.     
  1883.           fd = open (filename, O_TRUNC | O_WRONLY | O_CREAT, 0666);
  1884.           if (fd < 0)
  1885.         {
  1886.           if (!redirectee->quoted)
  1887.             free (document);
  1888.           return (errno);
  1889.         }
  1890.           write (fd, document, document_index);
  1891.           close (fd);
  1892.           if (!redirectee->quoted)
  1893.         free (document);
  1894.  
  1895.           /* Make the document really temporary.  Also make it the
  1896.          input. */
  1897.           fd = open (filename, O_RDONLY, 0666);
  1898.  
  1899.           if (unlink (filename) < 0 || fd < 0)
  1900.         return (errno);
  1901.  
  1902.           if (for_real)
  1903.         {
  1904.           if (remembering)
  1905.             /* Only setup to undo it if the thing to undo is active. */
  1906.             if ((fd != redirector) &&
  1907.             (fcntl (redirector, F_GETFD, 0) != -1))
  1908.               add_undo_redirect (redirector);
  1909.             else
  1910.               add_undo_close_redirect (redirector);
  1911.  
  1912.           if (dup2 (fd, redirector) < 0)
  1913.             return (errno);
  1914.  
  1915.           SET_OPEN_ON_EXEC (redirector);
  1916.  
  1917.           if (set_clexec && (redirector > 2))
  1918.             SET_CLOSE_ON_EXEC (redirector);
  1919.         }
  1920.           close (fd);
  1921.         }
  1922.       }
  1923.       }
  1924.       break;
  1925.  
  1926.     case r_duplicating:
  1927.       if (for_real)
  1928.     {
  1929.       if (remembering)
  1930.         /* Only setup to undo it if the thing to undo is active. */
  1931.         if (((int)redirectee != redirector) &&
  1932.         (fcntl (redirector, F_GETFD, 0) != -1))
  1933.           add_undo_redirect (redirector);
  1934.         else
  1935.           add_undo_close_redirect (redirector);
  1936.  
  1937.       /* This is correct.  2>&1 means dup2 (1, 2); */
  1938.       dup2 ((int)redirectee, redirector);
  1939.  
  1940.       SET_OPEN_ON_EXEC (redirector);
  1941.  
  1942.       /* First duplicate the close-on-exec state of redirectee.  dup2
  1943.          leaves the flag unset on the new descriptor, which means it
  1944.          stays open.  Only set the close-on-exec bit for file descriptors
  1945.          greater than 2 in any case, since 0-2 should always be open
  1946.          unless closed by something like `exec 2<&-'. */
  1947.       /* if ((already_set || set_unconditionally) && (ok_to_set))
  1948.             set_it () */
  1949.  
  1950.       if (((fcntl (redirectee, F_GETFD, 0) == 1) || set_clexec) &&
  1951.            (redirector > 2))
  1952.         SET_CLOSE_ON_EXEC (redirector);
  1953.     }
  1954.       break;
  1955.  
  1956.     case r_close_this:
  1957.       if (for_real)
  1958.     {
  1959.       /* Don't undo the redirection, you dummy!  You're closing it! */
  1960.       close (redirector);
  1961.     }
  1962.       break;
  1963.     }
  1964.   return (0);
  1965. }
  1966.  
  1967. #define SHELL_FD_BASE    10
  1968.  
  1969. /* Remember the file descriptor associated with the slot FD,
  1970.    on REDIRECTION_UNDO_LIST.  Note that the list will be reversed
  1971.    before it is executed. */
  1972. add_undo_redirect (fd)
  1973.      int fd;
  1974. {
  1975.   int new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
  1976.   int clexec_flag = fcntl (fd, F_GETFD, 0);
  1977.   REDIRECT *new_redirect, *closer;
  1978.  
  1979.   if (new_fd < 0)
  1980.     {
  1981.       file_error ("redirection error");
  1982.       return (-1);
  1983.     }
  1984.   else
  1985.     {
  1986.       closer = make_redirection (new_fd, r_close_this, 0);
  1987.       new_redirect = make_redirection (fd, r_duplicating, new_fd);
  1988.       new_redirect->next = closer;
  1989.       closer->next = redirection_undo_list;
  1990.       redirection_undo_list = new_redirect;
  1991.       /*
  1992.        * File descriptors used only for saving others should always be
  1993.        * marked close-on-exec.  Unfortunately, we have to preserve the
  1994.        * close-on-exec state of the file descriptor we are saving, since
  1995.        * fcntl (F_DUPFD) sets the new file descriptor to remain open
  1996.        * across execs.  If, however, the file descriptor whose state we
  1997.        * are saving is <= 2, we can just set the close-on-exec flag,
  1998.        * because file descriptors 0-2 should always be open-on-exec,
  1999.        * and the restore above in do_redirection() will take care of it.
  2000.        */
  2001.       if (clexec_flag || fd < 3)
  2002.     SET_CLOSE_ON_EXEC (new_fd);
  2003.     }
  2004.   return (0);
  2005. }
  2006.  
  2007. /* Set up to close FD when we are finished with the current command
  2008.    and its redirections. */
  2009. add_undo_close_redirect (fd)
  2010.      int fd;
  2011. {
  2012.   REDIRECT *closer;
  2013.  
  2014.   closer = make_redirection (fd, r_close_this, 0);
  2015.   closer->next = redirection_undo_list;
  2016.   redirection_undo_list = closer;
  2017. }
  2018.  
  2019. intern_function (name, function)
  2020.      WORD_DESC *name;
  2021.      COMMAND *function;
  2022. {
  2023.   SHELL_VAR *var;
  2024.  
  2025.   if (!check_identifier (name))
  2026.     return (EXECUTION_FAILURE);
  2027.  
  2028.   var = find_function (name->word);
  2029.   if (var && readonly_p (var))
  2030.     {
  2031.       report_error ("%s: readonly function", var->name);
  2032.       return (EXECUTION_FAILURE);
  2033.     }
  2034.  
  2035.   bind_function (name->word, function);
  2036.   return (EXECUTION_SUCCESS);
  2037. }
  2038.  
  2039. /* Make sure that identifier is a valid shell identifier, i.e.
  2040.    does not contain a dollar sign, nor is quoted in any way.  Nor
  2041.    does it consist of all digits. */
  2042. check_identifier (word)
  2043.      WORD_DESC *word;
  2044. {
  2045.   if (word->dollar_present || word->quoted || all_digits (word->word))
  2046.     {
  2047.       report_error ("`%s' is not a valid identifier", word->word);
  2048.       return (0);
  2049.     }
  2050.   else
  2051.     return (1);
  2052. }
  2053.  
  2054. /* Return non-zero if all of the characters in STRING are digits. */
  2055. all_digits (string)
  2056.      char *string;
  2057. {
  2058.   while (*string)
  2059.     {
  2060.       if (!digit (*string))
  2061.     return (0);
  2062.       else
  2063.     string++;
  2064.     }
  2065.   return (1);
  2066. }
  2067.  
  2068. #define u_mode_bits(x) (((x) & 0000700) >> 6)
  2069. #define g_mode_bits(x) (((x) & 0000070) >> 3)
  2070. #define o_mode_bits(x) (((x) & 0000007) >> 0)
  2071. #define X_BIT(x) (x & 1)
  2072.  
  2073. /* Non-zero if the last call to executable_file () found
  2074.    the file, but stated that it wasn't executable. */
  2075. int file_exists_p = 0;
  2076.  
  2077. /* Return non-zero if FILE is an executable file, otherwise 0.
  2078.    Note that this function is the definition of what an
  2079.    executable file is; do not change this unless YOU know
  2080.    what an executable file is. */
  2081. executable_file (file)
  2082.      char *file;
  2083. {
  2084.   struct stat finfo;
  2085.   static int user_id = -1;
  2086.  
  2087.   /* If the file doesn't exist, or is a directory, then we are
  2088.      not interested. */
  2089.   file_exists_p = !stat (file, &finfo);
  2090.  
  2091.   if (!file_exists_p || S_ISDIR (finfo.st_mode))
  2092.     return (0);
  2093.  
  2094.   /* By definition, the only other criteria is that the file has
  2095.      an execute bit set that we can use. */
  2096.   if (user_id == -1)
  2097.     user_id = geteuid ();
  2098.  
  2099.   /* Root only requires execute permission for any of owner, group or
  2100.      others to be able to exec a file. */
  2101.   if (user_id == 0)
  2102.     {
  2103.       int bits;
  2104.  
  2105.       bits = (u_mode_bits (finfo.st_mode) |
  2106.           g_mode_bits (finfo.st_mode) |
  2107.           o_mode_bits (finfo.st_mode));
  2108.  
  2109.       return (X_BIT (bits));
  2110.     }
  2111.  
  2112.   /* If we are the owner of the file, the owner execute bit applies. */
  2113.   if (user_id == finfo.st_uid)
  2114.     return (X_BIT (u_mode_bits (finfo.st_mode)));
  2115.  
  2116.   /* If we are in the owning group, the group permissions apply. */
  2117.   if (group_member (finfo.st_gid))
  2118.     return (X_BIT (g_mode_bits (finfo.st_mode)));
  2119.  
  2120.   /* If `others' have execute permission to the file, then so do we,
  2121.      since we are also `others'. */
  2122.   return (X_BIT (o_mode_bits (finfo.st_mode)));
  2123. }
  2124.  
  2125. #if defined (HAVE_MULTIPLE_GROUPS)
  2126. /* The number of groups that this user is a member of. */
  2127. static int ngroups = 0;
  2128. static int *group_array = (int *)NULL;
  2129. static int default_group_array_size = 0;
  2130. #endif /* HAVE_MULTIPLE_GROUPS */
  2131.  
  2132. /* Return non-zero if GID is one that we have in our groups list. */
  2133. group_member (gid)
  2134.      int gid;
  2135. {
  2136. #if ! defined (HAVE_MULTIPLE_GROUPS)
  2137.   return ((gid == getgid ()) || (gid == getegid ()));
  2138. #else
  2139.   register int i;
  2140.  
  2141.   /* getgroups () returns the number of elements that it was able to
  2142.      place into the array.  We simply continue to call getgroups ()
  2143.      until the number of elements placed into the array is smaller than
  2144.      the physical size of the array. */
  2145.  
  2146.   while (ngroups == default_group_array_size)
  2147.     {
  2148.       default_group_array_size += 64;
  2149.  
  2150.       group_array = (int *)
  2151.     xrealloc (group_array,
  2152.           default_group_array_size * sizeof (int));
  2153.  
  2154.       ngroups = getgroups (default_group_array_size, group_array);
  2155.     }
  2156.  
  2157.   /* In case of error, the user loses. */
  2158.   if (ngroups < 0)
  2159.     return (0);
  2160.  
  2161.   /* Search through the list looking for GID. */
  2162.   for (i = 0; i < ngroups; i++)
  2163.     if (gid == group_array[i])
  2164.       return (1);
  2165.  
  2166.   return (0);
  2167. #endif /* HAVE_MULTIPLE_GROUPS */
  2168. }
  2169.  
  2170. /* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()
  2171.    encounters a `.' as the directory pathname while scanning the
  2172.    list of possible pathnames; i.e., if `.' comes before the directory
  2173.    containing the file of interest. */
  2174. int dot_found_in_search = 0;
  2175.  
  2176. /* Locate the executable file referenced by NAME, searching along
  2177.    the contents of the shell PATH variable.  Return a new string
  2178.    which is the full pathname to the file, or NULL if the file
  2179.    couldn't be found. If a file is found that isn't executable,
  2180.    and that is the only match, then return that. */
  2181. char *
  2182. find_user_command (name)
  2183.      char *name;
  2184. {
  2185.   char *find_user_command_internal ();
  2186. /**
  2187.  ** (sjk)++ Check the extensions {.tos/.ttp/.prg} for a user command.
  2188.  **/
  2189. #if defined(atarist)
  2190.   char *win,*name_suffix;
  2191.   name_suffix = (char *)alloca(4 + strlen(name)); 
  2192. #endif
  2193.  
  2194. #if !defined(atarist)
  2195.  
  2196.   return (find_user_command_internal (name, 1));
  2197.  
  2198. #else  /* Must be an Atari ST */
  2199.  
  2200.   win = find_user_command_internal(name, 1);
  2201.   if (win != (char *)NULL) return(win);
  2202.  
  2203.   strcpy(name_suffix,name);
  2204.   strcat(name_suffix,".ttp");
  2205.   win = (char *)find_user_command_internal(name_suffix, 1);
  2206.   if (win != (char *)NULL) return(win);
  2207.  
  2208.   strcpy(name_suffix,name);
  2209.   strcat(name_suffix,".tos");
  2210.   win = (char *)find_user_command_internal(name_suffix, 1);
  2211.   if (win != (char *)NULL) return(win);
  2212.  
  2213.   strcpy(name_suffix,name);
  2214.   strcat(name_suffix,".prg");
  2215.   win = (char *)find_user_command_internal(name_suffix, 1);
  2216.   if (win != (char *)NULL) return(win);
  2217.  
  2218.   return(win);
  2219. #endif                               
  2220. }
  2221.  
  2222. /* Locate the file referenced by NAME, searching along the contents
  2223.    of the shell PATH variable.  Return a new string which is the full
  2224.    pathname to the file, or NULL if the file couldn't be found. This
  2225.    returns the first file found. */
  2226. char *
  2227. find_path_file (name)
  2228.      char *name;
  2229. {
  2230.   char *find_user_command_internal ();
  2231.  
  2232.   return (find_user_command_internal (name, 0));
  2233. }
  2234.  
  2235. char *
  2236. find_user_command_internal (name, must_be_executable)
  2237.      char *name;
  2238.      int must_be_executable;
  2239. {
  2240.   char *path_list;
  2241.   char *find_user_command_in_path ();
  2242.  
  2243.   path_list = get_string_value ("PATH");
  2244.   if (!path_list) return (savestring (name));
  2245.  
  2246.   return (find_user_command_in_path (name, path_list, must_be_executable));
  2247. }
  2248.  
  2249. char *
  2250. user_command_matches (name, must_be_executable, state)
  2251.      char *name;
  2252.      int must_be_executable;
  2253.      int state;
  2254. {
  2255.   register int i;
  2256.   char *path_list;
  2257.   int  path_index;
  2258.   char *path_element;
  2259.   char *match;
  2260.   static char **match_list = NULL;
  2261.   static int match_list_size = 0;
  2262.   static int match_index = 0;
  2263.   char *extract_colon_unit ();
  2264.  
  2265.   if (!state)
  2266.     {
  2267.       /* Create the list of matches. */
  2268.       if (!match_list)
  2269.     {
  2270.       match_list =
  2271.         (char **) xmalloc ((match_list_size = 5) * sizeof(char *));
  2272.  
  2273.       for (i = 0; i < match_list_size; i++)
  2274.         match_list[i] = 0;
  2275.     }
  2276.  
  2277.       /* Clear out the old match list. */
  2278.       for (i = 0; i < match_list_size; i++)
  2279.     match_list[i] = NULL;
  2280.  
  2281.       /* We haven't found any files yet. */
  2282.       match_index = 0;
  2283.  
  2284.       path_list = get_string_value ("PATH");
  2285.       path_index = 0;
  2286.  
  2287.       while (path_element = extract_colon_unit (path_list, &path_index))
  2288.     {
  2289.       char *find_user_command_in_path ();
  2290.  
  2291.       match =
  2292.         find_user_command_in_path (name, path_element, must_be_executable);
  2293.  
  2294.       free (path_element);
  2295.  
  2296.       if (!match)
  2297.         continue;
  2298.  
  2299.       if (match_index + 1 == match_list_size)
  2300.         match_list =
  2301.           (char **)xrealloc ((char *)match_list,
  2302.                  ((match_list_size += 10) + 1) * sizeof (char *));
  2303.       match_list[match_index++] = match;
  2304.       match_list[match_index] = (char *)NULL;
  2305.     }
  2306.  
  2307.       /* We haven't returned any strings yet. */
  2308.       match_index = 0;
  2309.     }
  2310.  
  2311.   match = match_list[match_index];
  2312.  
  2313.   if (match)
  2314.     match_index++;
  2315.  
  2316.   return(match);
  2317. }
  2318.  
  2319. /* Return 1 if PATH1 and PATH2 are the same file.  This is kind of
  2320.    expensive.   If non-NULL STP1 and STP2 point to stat structures
  2321.    corresponding to PATH1 and PATH2, respectively. */
  2322. int
  2323. same_file (path1, path2, stp1, stp2)
  2324.      char *path1, *path2;
  2325.      struct stat *stp1, *stp2;
  2326. {
  2327.   struct stat st1, st2;
  2328.  
  2329.   if (stp1 == NULL)
  2330.     {
  2331.       if (stat (path1, &st1) != 0)
  2332.     return (0);
  2333.       stp1 = &st1;
  2334.     }
  2335.  
  2336.   if (stp2 == NULL)
  2337.     {
  2338.       if (stat (path2, &st2) != 0)
  2339.     return (0);
  2340.       stp2 = &st2;
  2341.     }
  2342.  
  2343.   return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
  2344. }
  2345.  
  2346. /* This does the dirty work for find_path_file () and
  2347.    find_user_command (). */
  2348. char *
  2349. find_user_command_in_path (name, path_list, must_be_executable)
  2350.      char *name;
  2351.      char *path_list;
  2352.      int must_be_executable;
  2353. {
  2354.   extern char *extract_colon_unit ();
  2355.   extern int file_exists_p;
  2356.   char *full_path;
  2357.   char *path;
  2358.   int path_index = 0;
  2359.   struct stat dot_stat_buf;
  2360.   int name_len = strlen (name);
  2361.  
  2362.   /* The file name which we would try to execute, except that it isn't
  2363.      possible to execute it.  This is the first file that matches the
  2364.      name that we are looking for while we are searching $PATH for a
  2365.      suitable one to execute.  If we cannot find a suitable executable
  2366.      file, then we use this one. */
  2367.   char *file_to_lose_on = (char *)NULL;
  2368.  
  2369.   /* We haven't started looking, so we certainly haven't seen
  2370.      a `.' as the directory path yet. */
  2371.   dot_found_in_search = 0;
  2372.  
  2373.  
  2374.   if (absolute_program (name))
  2375.     {
  2376.       full_path = (char *)xmalloc (1 + strlen(name));
  2377.       strcpy (full_path, name);
  2378.  
  2379.       if (executable_file (full_path) || file_exists_p)
  2380.     {
  2381.       return (full_path);
  2382.     }
  2383.       else
  2384.     {
  2385.       free (full_path);
  2386.       return ((char *)NULL);
  2387.     }
  2388.     }
  2389.  
  2390.   stat (".", &dot_stat_buf);   /* should set in get_working_directory */
  2391.  
  2392.   while (path_list && path_list[path_index])
  2393.     {
  2394.       path = extract_colon_unit (path_list, &path_index);
  2395.       if (!path || !*path)
  2396.     {
  2397.       if (path)
  2398.         free (path);
  2399.       path = savestring ("."); /* by definition. */
  2400.     }
  2401.  
  2402.       if (*path == '~')
  2403.     {
  2404.       char *tilde_expand ();
  2405.       char *t = tilde_expand (path);
  2406.       free (path);
  2407.       path = t;
  2408.     }
  2409.  
  2410.       /* Remember the location of "." in the path, in all its forms (as long as
  2411.      they begin with a `.', e.g. `./.') */
  2412.       if ((*path == '.') && same_file (".", path, &dot_stat_buf, (struct stat *)NULL))
  2413.     dot_found_in_search = 1;
  2414.  
  2415.       full_path = (char *)xmalloc (2 + strlen (path) + name_len);
  2416.       sprintf (full_path, "%s/%s", path, name);
  2417.       free (path);
  2418.  
  2419.       if (executable_file (full_path) ||
  2420.       (!must_be_executable && file_exists_p))
  2421.     {
  2422.       if (file_to_lose_on)
  2423.         free (file_to_lose_on);
  2424.       return (full_path);
  2425.     }
  2426.       else
  2427.     {
  2428.       if (file_exists_p && !file_to_lose_on)
  2429.         file_to_lose_on = full_path;
  2430.       else
  2431.         free (full_path);
  2432.     }
  2433.     }
  2434.  
  2435.   /* If we found a file with the right name, but not one that is
  2436.      executable, then return the one with the right name. */
  2437.   if (file_to_lose_on)
  2438.     return (file_to_lose_on);
  2439.   else
  2440.     return (char *)NULL;
  2441. }
  2442.  
  2443. /* Given a string containing units of information separated by colons,
  2444.    return the next one pointed to by INDEX, or NULL if there are no more.
  2445.    Advance INDEX to the character after the colon. */
  2446. char *
  2447. extract_colon_unit (string, index)
  2448.      char *string;
  2449.      int *index;
  2450. {
  2451.   int i, start;
  2452.  
  2453.   i = *index;
  2454.  
  2455.   if (!string || (i >= strlen (string)))
  2456.     return ((char *)NULL);
  2457.  
  2458.   /*
  2459.    * Each call to this routine leaves the index pointing at a colon if there
  2460.    * is more to the path.  If i is > 0, then increment past the `:'.  (If i
  2461.    * is 0, then the path has a leading colon.  If this is not done, the
  2462.    * second call to this routine will always return NULL, which will be
  2463.    * translated to  `.', even if `.' is not in the path.  Trailing colons
  2464.    * are handled OK by the `else' part of the if statement; it returns a null
  2465.    * string for the last component of a path with a trailing colon, and the
  2466.    * routines that call this will translate that to `.'.
  2467.    */
  2468.  
  2469.   if (i && string[i] == ':')
  2470.     i++;
  2471.  
  2472.   start = i;
  2473.  
  2474.   while (string[i] && string[i] != ':') i++;
  2475.  
  2476.   *index = i;
  2477.  
  2478.   if (i == start)
  2479.     {
  2480.       if (!string[i])
  2481.     return ((char *)NULL);
  2482.  
  2483.       (*index)++;
  2484.  
  2485.       return (savestring (""));
  2486.     }
  2487.   else
  2488.     {
  2489.       char *value;
  2490.  
  2491.       value = (char *)xmalloc (1 + (i - start));
  2492.       strncpy (value, &string[start], (i - start));
  2493.       value [i - start] = '\0';
  2494.  
  2495.       return (value);
  2496.     }
  2497. }
  2498.  
  2499. /* Return non-zero if the characters from SAMPLE are not all valid
  2500.    characters to be found in the first line of a shell script.  We
  2501.    check upto the first newline, or SAMPLE_LEN, whichever comes first.
  2502.    All of the characters must be printable or whitespace. */
  2503.  
  2504. #if !defined (isspace)
  2505. #define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f')
  2506. #endif
  2507.  
  2508. #if !defined (isprint)
  2509. #define isprint(c) (isletter(c) || digit(c) || ispunct(c))
  2510. #endif
  2511.  
  2512. int
  2513. check_binary_file (sample, sample_len)
  2514.      unsigned char *sample;
  2515.      int sample_len;
  2516. {
  2517.   register int i;
  2518.  
  2519.   for (i = 0; i < sample_len; i++)
  2520.     {
  2521.       if (sample[i] == '\n')
  2522.     break;
  2523.  
  2524.       if (!isspace(sample[i]) && !isprint (sample[i]))
  2525.     return (1);
  2526.     }
  2527.   return (0);
  2528. }
  2529.